package com.bayss.web.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bayss.core.DokoServerException;
import com.bayss.core.DokoServerExceptionFactor;
import com.bayss.core.constant.ResultMsg;
import com.bayss.core.entity.order.Order;
import com.bayss.core.entity.order.OrderComment;
import com.bayss.core.entity.order.OrderRefund;
import com.bayss.core.entity.user.UserInfo;
import com.bayss.core.enums.OrderOp;
import com.bayss.core.model.OrderMsg;
import com.bayss.core.model.ParamGInfo;
import com.bayss.core.model.ProcessInfo;
import com.bayss.core.model.ShowOrder;
import com.bayss.core.service.code.CodeBaseService;
import com.bayss.core.service.order.OrderService;
import com.bayss.core.service.user.UserService;
import com.bayss.core.util.FileUtil;
import com.bayss.web.uresponse.DeliverymanResponse;
import com.bayss.web.uresponse.UserResponse;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 订单操作
 *
 * @author yangjian
 */
@RestController
public class OrderController extends ApiBaseController {

    private final OrderService orderService;

    private final UserService userService;

    private final CodeBaseService codeBaseService;

    @Autowired
    public OrderController(OrderService orderService, UserService userService, CodeBaseService codeBaseService) {
        this.orderService = orderService;
        this.userService = userService;
        this.codeBaseService = codeBaseService;
    }

    /**
     * 订单创建
     */
    @PostMapping("/order/create.json")
    public ResultMsg create(UserResponse userResponse,
                            @RequestParam(name = "stationId") Long stationId,
                            @RequestParam(name = "addrId", required = false, defaultValue = "0") Long addrId,
                            @RequestParam(name = "orderMod") Integer orderMod,
                            @RequestParam(name = "orderType") Integer orderType,
                            @RequestParam(name = "channel") Integer channel,
                            @RequestParam(name = "code", required = false, defaultValue = "") String code,
                            @RequestParam(name = "preId", required = false, defaultValue = "0") Long preId,
                            @RequestParam(name = "isAtOnce", required = false, defaultValue = "0") Integer isAtOnce,
                            @RequestParam(name = "reserveTel", required = false, defaultValue = "") String reserveTel,
                            @RequestParam(name = "orderDesc", required = false, defaultValue = "") String orderDesc,
                            @RequestParam(name = "skuCodeList") String orderGInfoList) {
        UserInfo userInfo = userResponse.getUserInfo();
        List<ParamGInfo> paramGInfos = JSONArray.parseArray(orderGInfoList, ParamGInfo.class);
        Order order = Order.builder()
                .stationId(stationId)
                .uid(userInfo.getId())
                .addrId(addrId)
                .reserveTel(reserveTel)
                .orderMod(orderMod)
                .orderType(orderType)
                .preId(preId)
                .channel(channel)
                .orderDesc(orderDesc)
                .build();
        return ResultMsg.success(orderService.createOrder(order, paramGInfos, userInfo.getOpenId(), isAtOnce, code));
    }

    /**
     * 价格计算
     */
    @PostMapping("/order/cost_price.json")
    public ResultMsg costPrice(UserResponse userResponse,
                                @RequestParam(name = "stationId", required = false, defaultValue = "0") Long stationId,
                                @RequestParam(name = "addrId", required = false, defaultValue = "0") Long addrId,
                                @RequestParam(name = "orderMod", required = false, defaultValue = "0") Integer orderMod,
                                @RequestParam(name = "orderType", required = false, defaultValue = "0") Integer orderType,
                                @RequestParam(name = "preId", required = false, defaultValue = "0") Long preId,
                                @RequestParam(name = "skuCodeList") String orderGInfoList) {
        UserInfo userInfo = userResponse.getUserInfo();
        List<ParamGInfo> paramGInfos = JSONArray.parseArray(orderGInfoList, ParamGInfo.class);
        return ResultMsg.success(orderService.costPrice(paramGInfos, stationId, addrId, orderMod, orderType, preId, userInfo.getId()));
    }

    /**
     * 我的订单
     */
    @RequestMapping("/order/get.json")
    public ResultMsg costPrice(UserResponse userResponse,
                               @RequestParam(name = "maxId", required = false, defaultValue = "0") Long maxId,
                               @RequestParam(name = "count", required = false, defaultValue = "5") Integer count,
                               @RequestParam(name = "tab", required = false, defaultValue = "1") Integer tab) {
        UserInfo userInfo = userResponse.getUserInfo();
        List<ShowOrder> showOrders = orderService.getOrders(userInfo.getId(), maxId, count, tab);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("showOrders", showOrders);
        if (showOrders.size() < count) {
            jsonObject.put("maxId", -1);
        } else {
            jsonObject.put("maxId", showOrders.get(showOrders.size()-1).getId());
        }
        return ResultMsg.success(jsonObject);
    }

    /**
     * 骑手订单
     */
    @RequestMapping("/order/deliveryman_get.json")
    public ResultMsg costPrice(DeliverymanResponse deliverymanResponse,
                               @RequestParam(name = "isFinish", required = false, defaultValue = "0") Integer isFinish,
                               @RequestParam(name = "maxId", required = false, defaultValue = "0") Long maxId,
                               @RequestParam(name = "count", required = false, defaultValue = "5") Integer count) {
        List<ShowOrder> showOrders = orderService.getDeliverymanOrders(deliverymanResponse.getDeliId(), maxId, count, isFinish);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("showOrders", showOrders);
        if (showOrders.size() < count) {
            jsonObject.put("maxId", -1);
        } else {
            jsonObject.put("maxId", showOrders.get(showOrders.size()-1).getId());
        }
        return ResultMsg.success(jsonObject);
    }

    /**
     * 订单详情
     */
    @RequestMapping("/order/desc.json")
    public ResultMsg orderDesc(@RequestParam(name = "orderNo") String orderNo) {
        return ResultMsg.success(orderService.getOrderDesc(orderNo));
    }

    /**
     * 订单取消
     */
    @PostMapping("/order/cancel.json")
    public ResultMsg orderCancel(@RequestParam(name = "orderNo") String orderNo) {
        boolean res = orderService.orderCancel(orderNo);
        if (!res) {
            throw new DokoServerException(DokoServerExceptionFactor.DEFAULT, "cancel order is fail");
        }
        return ResultMsg.success(true);
    }

    /**
     * 订单支付
     */
    @PostMapping("/order/pay.json")
    public ResultMsg orderPay(@RequestParam(name = "orderNo") String orderNo) {
        return ResultMsg.success(orderService.orderPay(orderNo));
    }

    /**
     * 商户接单
     */
    @PostMapping("/order/revc.json")
    public ResultMsg revc(@RequestParam(name = "orderNo") String orderNo) {
        ProcessInfo processInfo = ProcessInfo.builder()
                .orderNo(orderNo)
                .build();
        OrderMsg<String> res = orderService.handlerOrder(OrderOp.ORDER_REVC, processInfo);
        if (res.isOk()) {
            return ResultMsg.success();
        }
        throw new DokoServerException(DokoServerExceptionFactor.DEFAULT, "商户接单失败");
    }


    /**
     * 接受派单
     */
    @PostMapping("/order/transfer_ack.json")
    public ResultMsg transferAck(@RequestParam(name = "orderNo") String orderNo) {
        ProcessInfo processInfo = ProcessInfo.builder()
                .orderNo(orderNo)
                .build();
        OrderMsg<String> res = orderService.handlerOrder(OrderOp.ORDER_SEND_WAIT, processInfo);
        if (res.isOk()) {
            return ResultMsg.success();
        }
        throw new DokoServerException(DokoServerExceptionFactor.DEFAULT, "骑手接单失败");
    }

    /**
     * 确认取餐
     */
    @PostMapping("/order/take_meals_ack.json")
    public ResultMsg takeMealsAck(@RequestParam(name = "orderNo") String orderNo) {
        ProcessInfo processInfo = ProcessInfo.builder()
                .orderNo(orderNo)
                .build();
        OrderMsg<String> res = orderService.handlerOrder(OrderOp.ORDER_SENDING, processInfo);
        if (res.isOk()) {
            return ResultMsg.success();
        }
        throw new DokoServerException(DokoServerExceptionFactor.DEFAULT, "骑手取餐失败");
    }

    /**
     * 确认送达 (订单完成)
     */
    @PostMapping("/order/send_ack.json")
    public ResultMsg sendAck(@RequestParam(name = "orderNo") String orderNo,
                             @RequestParam(name = "revcCode", required = false, defaultValue = "") String revcCode) {
        ProcessInfo processInfo = ProcessInfo.builder()
                .orderNo(orderNo)
                .revcCode(revcCode)
                .build();
        OrderMsg<String> res = orderService.handlerOrder(OrderOp.ORDER_SENDED, processInfo);
        if (res.isOk()) {
            return ResultMsg.success();
        }
        throw new DokoServerException(DokoServerExceptionFactor.DEFAULT, "确认送达失败");
    }

    /**
     * 评价
     */
    @PostMapping("/order/comment.json")
    public ResultMsg comment(UserResponse userResponse,
                             @RequestParam(name = "orderNo") Long orderNo,
                             @RequestParam(name = "gGradeInfo") String gGradeInfo,
                             @RequestParam(name = "gMsg") String gMsg,
                             @RequestParam(name = "gUrl") String[] gUrls,
                             @RequestParam(name = "hMsg") String hMsg,
                             @RequestParam(name = "hGrade") Float hGrade) {
        if (gUrls != null && gUrls.length > 0) {
            for (int i=0; i<gUrls.length; i++) {
                gUrls[i] = FileUtil.formatImgUrl(gUrls[i]);
            }
        }
        OrderComment orderComment = OrderComment.builder()
                .uid(userResponse.getUid())
                .orderNo(String.valueOf(orderNo))
                .gGradeInfo(gGradeInfo)
                .gMsg(gMsg)
                .gUrl(StringUtils.join(gUrls, ","))
                .hMsg(hMsg)
                .hGrade(hGrade)
                .build();
        return ResultMsg.success(orderService.comment(orderComment));
    }

    /**
     * 获取评价信息
     */
    @GetMapping("/order/comment/get.json")
    public ResultMsg getComments(@RequestParam(name = "stationId", required = false, defaultValue = "-1") Long stationId,
                                 @RequestParam(name = "status", required = false, defaultValue = "-1") Integer status,
                                 @RequestParam(name = "display", required = false, defaultValue = "-1") Integer display,
                                 @RequestParam(name = "page", required = false, defaultValue = "1") Integer page,
                                 @RequestParam(name = "pageSize", required = false, defaultValue = "10") Integer pageSize) {
        return ResultMsg.success(orderService.getComments(stationId, status, display, page, pageSize));
    }

    /**
     * 退款
     */
    @PostMapping("/order/refund.json")
    public ResultMsg refund(UserResponse userResponse,
                            @RequestParam(name = "orderNo") String orderNo,
                            @RequestParam(name = "refundResource") String refundResource,
                            @RequestParam(name = "refundDesc", required = false, defaultValue = "") String refundDesc,
                            @RequestParam(name = "refundUrl", required = false, defaultValue = "") String refundUrl,
                            @RequestParam(name = "orderGInfoList") String orderGInfoList) {
        UserInfo userInfo = userResponse.getUserInfo();
        OrderRefund orderRefund = OrderRefund.builder()
                .orderNo(orderNo)
                .refundDesc(refundDesc)
                .refundResource(refundResource)
                .refundStatus(0)
                .refundUrl(refundUrl)
                .refundSkus(orderGInfoList)
                .uid(userInfo.getId())
                .build();
        return ResultMsg.success(orderService.refund(orderRefund));
    }

    /**
     * 短信验证码
     */
    @PostMapping("/order/sms.json")
    public ResultMsg orderSms(UserResponse userResponse, @RequestParam(name = "tel", required = false, defaultValue = "") String tel) {
        return ResultMsg.success(orderService.orderSms(userResponse.getUid(), tel));
    }

    /**
     * 获取评价信息
     */
    @GetMapping("/order/refund_reason/get.json")
    public ResultMsg getRefundReason() {
        return ResultMsg.success(codeBaseService.getCodesValueByCode("refund_reason"));
    }
}
